package zhoug.demo.chart2.chart;

import android.util.SparseIntArray;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;

import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.model.GradientColor;
import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;
import zhoug.chart.MPChartColors;
import zhoug.chart.MPChartConfig;
import zhoug.chart.charts.MPBarChart;
import zhoug.chart.charts.MPCombinedChart;
import zhoug.chart.charts.MPLineChart;
import zhoug.chart.core.MPBarKey;
import zhoug.chart.core.MPCombinedKey;
import zhoug.chart.core.MPConstant;
import zhoug.chart.core.styleconfig.IMPBarStyleConfig;
import zhoug.chart.core.styleconfig.IMPCombinedStyleConfig;
import zhoug.chart.core.styleconfig.IMPLineStyleConfig;
import zhoug.chart.data.HkChartData;
import zhoug.chart.formatters.MPDataSetValueFormatter;
import zhoug.chart.formatters.MPPercentAxisLabelFormatter;
import zhoug.chart.markers.MPBaseViewHolder;
import zhoug.chart.markers.MPCombinedMarker;
import zhoug.chart.markers.MPMarkerData;
import zhoug.chart.utils.MPChartUtils;
import zhoug.chart.views.MPIconView;
import zhoug.chart.views.MPLegendViewGroup;
import zhoug.demo.chart2.BaseActivity;
import zhoug.demo.chart2.R;
import zhoug.common.http.SchedulerUtils;
import zhoug.common.utils.RandomUtils;
import zhoug.common.utils.TextUtils;

import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.disposables.Disposable;

/**
 * 混合图表
 *
 * @Author: zhoug
 * @Date: 2024-01-30
 * @Description:
 */
public class CombinedChartActivity extends BaseActivity {
    private int mXNum;
    private int mYNum;
    private boolean stack;
    private boolean autoScale;
    private boolean spaceIsPercent;
    private boolean arc;
    private boolean gradientColor;
    private boolean lineAttachAxis;
    private int oneScreenNum;
    private float barWidth;
    private float barSpace;
    private float groupSpace;

    private Switch mSwitchStack;
    private Switch mSwitchArc;
    private EditText mEtXSize;
    private EditText mEtYSize;
    private Switch mSwitchAutoScale;
    private EditText mEtOneScreenMinNum;
    private Switch mSwitchPercent;
    private EditText mEtBarWidth;
    private EditText mEtGroupSpace;
    private EditText mEtBarSpace;
    private Switch mSwitchGradientColors;
    private Button mBtnSetting;
    private MPCombinedChart mCombinedChart1;
    private MPCombinedChart mCombinedChart2;
    private SwipeRefreshLayout mSwipeRefreshLayout;
    private MPCombinedChart mCombinedChart3;
    private Switch mSwitchLineAttachAxis;
    private MPBarChart mBarChart;
    private MPLineChart mLineChart;
    private MPCombinedChart mCombinedChart11;
    private MPLineChart mLineChartPercent;
    private MPLegendViewGroup mLegendViewGroup1;

    @Override
    protected int getLayoutResId() {
        return R.layout.activity_combinedchart;
    }

    @Override
    protected void findViews() {
        mSwitchStack = findViewById(R.id.switchStack);
        mSwitchArc = findViewById(R.id.switchArc);
        mEtXSize = findViewById(R.id.et_xSize);
        mEtYSize = findViewById(R.id.et_ySize);
        mSwitchAutoScale = findViewById(R.id.switchAutoScale);
        mEtOneScreenMinNum = findViewById(R.id.et_oneScreenMinNum);
        mSwitchPercent = findViewById(R.id.switchPercent);
        mEtBarWidth = findViewById(R.id.et_barWidth);
        mEtGroupSpace = findViewById(R.id.et_groupSpace);
        mEtBarSpace = findViewById(R.id.et_barSpace);
        mSwitchGradientColors = findViewById(R.id.switchGradientColors);
        mBtnSetting = findViewById(R.id.btn_setting);
        mCombinedChart1 = findViewById(R.id.combinedChart1);
        mCombinedChart2 = findViewById(R.id.combinedChart2);
        mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);
        mCombinedChart3 = findViewById(R.id.combinedChart3);
        mSwitchLineAttachAxis = findViewById(R.id.switchLineAttachAxis);
        mBarChart = findViewById(R.id.barChart);
        mLineChart = findViewById(R.id.lineChart);
        mCombinedChart11 = findViewById(R.id.combinedChart11);
        mLineChartPercent = findViewById(R.id.lineChartPercent);
        mLegendViewGroup1 = findViewById(R.id.legendViewGroup1);
    }

    private static final int[] barColors = {MPChartColors.COLOR_RED, MPChartColors.COLOR_BLUE, MPChartColors.COLOR_GREEN,
            MPChartColors.COLOR_SOIL, MPChartColors.COLOR_DEEP_PURPLE, MPChartColors.COLOR_LAVENDER, MPChartColors.COLOR_GRASS_GREEN,};
    private static final int[] lineColors = {MPChartColors.COLOR_DARK_BLUE, MPChartColors.COLOR_CYAN, MPChartColors.COLOR_LIGHT_BLUE,
            MPChartColors.COLOR_ORANGE, MPChartColors.COLOR_DEEP_PURPLE, MPChartColors.COLOR_MINT_GREEN,};

    private static final List<GradientColor> gradientColors = Arrays.asList(
            new GradientColor(MPChartColors.COLOR_RED, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_RED)),
            new GradientColor(MPChartColors.COLOR_BLUE, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_BLUE)),
            new GradientColor(MPChartColors.COLOR_GREEN, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_GREEN)),
            new GradientColor(MPChartColors.COLOR_SOIL, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_SOIL)),
            new GradientColor(MPChartColors.COLOR_DEEP_PURPLE, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_DEEP_PURPLE)),
            new GradientColor(MPChartColors.COLOR_LAVENDER, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_LAVENDER)),
            new GradientColor(MPChartColors.COLOR_GRASS_GREEN, MPChartUtils.setColorAlphaPercent(0.2f, MPChartColors.COLOR_GRASS_GREEN))
    );

    @Override
    protected void init() {
        mLegendViewGroup1.setChart(mCombinedChart1);
        mCombinedChart1.getLegend().setEnabled(false);

        XAxis xAxis = mBarChart.getXAxis();
        xAxis.setDrawGridLines(true);
        xAxis = mLineChart.getXAxis();
        xAxis.setDrawGridLines(true);
        xAxis = mCombinedChart1.getXAxis();
        xAxis.setDrawGridLines(true);
        xAxis = mCombinedChart11.getXAxis();
        xAxis.setDrawGridLines(true);
        xAxis = mCombinedChart2.getXAxis();
        xAxis.setDrawGridLines(true);
        xAxis = mCombinedChart3.getXAxis();
        xAxis.setDrawGridLines(true);
        xAxis = mLineChartPercent.getXAxis();
        xAxis.setDrawGridLines(true);
        YAxis axisRight = mLineChartPercent.getAxisLeft();
        axisRight.setEnabled(true);
        axisRight.setValueFormatter(new MPPercentAxisLabelFormatter().setMultiply100(false));
        MPChartConfig.setPercentAxis(axisRight, false);
        //bar
        IMPBarStyleConfig barStyleConfig = mBarChart.getStyleConfig();
        barStyleConfig.setBarColors(barColors);
        //line
        IMPLineStyleConfig lineStyleConfig = mLineChart.getStyleConfig();
        lineStyleConfig.setLineColors(lineColors);
        lineStyleConfig = mLineChartPercent.getStyleConfig();
        lineStyleConfig.setLineColors(lineColors);

        //bar+line
        IMPCombinedStyleConfig styleConfig = mCombinedChart1.getStyleConfig();
        styleConfig.setBarColors(barColors);
        styleConfig.setLineColors(lineColors);

        styleConfig = mCombinedChart11.getStyleConfig();
        styleConfig.setBarColors(barColors);
        styleConfig.setLineColors(lineColors);

        //bar
        styleConfig = mCombinedChart2.getStyleConfig();
        styleConfig.setDefaultChartType(MPConstant.BAR_CHART);
        styleConfig.setBarColors(barColors);
        //line
        styleConfig = mCombinedChart3.getStyleConfig();
        styleConfig.setDefaultChartType(MPConstant.LINE_CHART);
        styleConfig.setLineColors(lineColors);


        mSwipeRefreshLayout.setOnRefreshListener(this::loadData);
        mBtnSetting.setOnClickListener(v -> {
            setting();
            loadData();
        });
        mSwitchStack.setOnCheckedChangeListener(onCheckedChangeListener);
        mSwitchAutoScale.setOnCheckedChangeListener(onCheckedChangeListener);
        mSwitchPercent.setOnCheckedChangeListener(onCheckedChangeListener);
        mSwitchArc.setOnCheckedChangeListener(onCheckedChangeListener);
        mSwitchGradientColors.setOnCheckedChangeListener(onCheckedChangeListener);
        mSwitchLineAttachAxis.setOnCheckedChangeListener(onCheckedChangeListener);

        final MPCombinedMarker combinedMarker = new MPCombinedMarker(this);
        combinedMarker.showSum(true);
        combinedMarker.setOnBindDataListener(new MPCombinedMarker.OnBindDataListener() {
            /**
             * x轴label
             *
             * @param tvXLabel
             * @param showSum
             * @param sum
             * @return false 使用默认的
             */
            @Override
            public boolean onBindXLabel(TextView tvXLabel, String xLabel, boolean showSum, float sum) {
                tvXLabel.setText("###" + xLabel);
                return true;
            }

            /**
             * listItem布局文件
             *
             * @return
             */
            @Override
            public int getListItemLayoutId() {
                return R.layout.combined_marker_test_item;
            }

            @Override
            public boolean onBindItemData(MPBaseViewHolder holder, MPMarkerData.YData data, int position, int viewType) {
                if (data != null) {
                    TextView tvLabel = holder.getView(R.id.tvLabel);
                    TextView tvValue = holder.getView(R.id.tvValue);
                    TextView tvPercent = holder.getView(R.id.tvPercent);
                    tvLabel.setText("#" + combinedMarker.getLabelFormat(data.getLabel()));
                    tvValue.setText(data.getFormatValue());
                }
                return true;
            }
        });
        mCombinedChart1.setMarker(combinedMarker);
        MPCombinedMarker combinedMarker2 = new MPCombinedMarker(this);
        combinedMarker2.showSum(true);
        mCombinedChart11.setMarker(combinedMarker2);
        combinedMarker2 = new MPCombinedMarker(this);
        combinedMarker2.showSum(true);
        mCombinedChart2.setMarker(combinedMarker2);
        combinedMarker2 = new MPCombinedMarker(this);
        combinedMarker2.showSum(true);
        mCombinedChart3.setMarker(combinedMarker2);
        combinedMarker2 = new MPCombinedMarker(this);
        combinedMarker2.showSum(true);
        mBarChart.setMarker(combinedMarker2);
        combinedMarker2 = new MPCombinedMarker(this);
        combinedMarker2.showSum(true);
        mLineChart.setMarker(combinedMarker2);
        combinedMarker2 = new MPCombinedMarker(this);
        combinedMarker2.showSum(true);
        mLineChartPercent.setMarker(combinedMarker2);
        mLineChartPercent.setDataSetValueFormatter(new MPDataSetValueFormatter().setPercent(true).setMultiply100(false));

        axisRight = mCombinedChart1.getAxisRight();
        axisRight.setEnabled(true);
        axisRight.setEnabled(true);
        axisRight.setValueFormatter(new MPPercentAxisLabelFormatter().setMultiply100(false));
        MPChartConfig.setPercentAxis(axisRight, false);
        mCombinedChart1.setLineDataSetValueFormatter(new MPDataSetValueFormatter().setPercent(true).setMultiply100(false));

        setting();
        loadData();
    }


    private CompoundButton.OnCheckedChangeListener onCheckedChangeListener = (buttonView, isChecked) -> {
        setting();
        loadData();
    };

    private void setting() {
        mXNum = TextUtils.parseInt(mEtXSize.getText().toString(), 6);
        mYNum = TextUtils.parseInt(mEtYSize.getText().toString(), 1);
        stack = mSwitchStack.isChecked();
        autoScale = mSwitchAutoScale.isChecked();
        spaceIsPercent = mSwitchPercent.isChecked();
        arc = mSwitchArc.isChecked();
        gradientColor = mSwitchGradientColors.isChecked();
        lineAttachAxis = mSwitchLineAttachAxis.isChecked();
        oneScreenNum = TextUtils.parseInt(mEtOneScreenMinNum.getText().toString(), 0);
        barWidth = TextUtils.parseFloat(mEtBarWidth.getText().toString(), 0);
        barSpace = TextUtils.parseFloat(mEtBarSpace.getText().toString(), 0);
        groupSpace = TextUtils.parseFloat(mEtGroupSpace.getText().toString(), 0);


        mBarChart.setBarTopArcEnable(arc);
        initBarStyleConfig(mBarChart.getStyleConfig());
        initLineStyleConfig(mLineChart.getStyleConfig());
        initLineStyleConfig(mLineChartPercent.getStyleConfig());
        initCombinedStyleConfig(mCombinedChart1.getStyleConfig());
        initCombinedStyleConfig(mCombinedChart11.getStyleConfig());
        initCombinedStyleConfig(mCombinedChart2.getStyleConfig());
        initCombinedStyleConfig(mCombinedChart3.getStyleConfig());
        mCombinedChart1.setBarTopArcEnable(arc);
        mCombinedChart11.setBarTopArcEnable(arc);
        mCombinedChart2.setBarTopArcEnable(arc);
        mCombinedChart3.setBarTopArcEnable(arc);
    }

    private void initBarStyleConfig(IMPBarStyleConfig styleConfig) {
        styleConfig.setStackBar(stack);
        styleConfig.setAutoScaleMax(autoScale);
        styleConfig.setSpaceIsPercent(spaceIsPercent);
        styleConfig.setOneScreen(oneScreenNum);
        styleConfig.setBarWidth(barWidth);
        styleConfig.setBarSpace(barSpace);
        styleConfig.setGroupSpace(groupSpace);
        if (gradientColor) {
            styleConfig.setGradientColors(gradientColors);
            styleConfig.setBarColors(null);
        } else {
            styleConfig.setGradientColors(null);
            styleConfig.setBarColors(barColors);
        }
    }

    private void initLineStyleConfig(IMPLineStyleConfig styleConfig) {
        styleConfig.setAutoScaleMax(autoScale);
        styleConfig.setLineAttachAxis(lineAttachAxis);
        styleConfig.setOneScreen(oneScreenNum);
    }


    private void initCombinedStyleConfig(IMPCombinedStyleConfig styleConfig) {
        styleConfig.setStackBar(stack);
        styleConfig.setAutoScaleMax(autoScale);
        styleConfig.setSpaceIsPercent(spaceIsPercent);
        styleConfig.setLineAttachAxis(lineAttachAxis);
        styleConfig.setOneScreen(oneScreenNum);
        styleConfig.setBarWidth(barWidth);
        styleConfig.setBarSpace(barSpace);
        styleConfig.setGroupSpace(groupSpace);
        if (gradientColor) {
            styleConfig.setGradientColors(gradientColors);
            styleConfig.setBarColors(null);
        } else {
            styleConfig.setGradientColors(null);
            styleConfig.setBarColors(barColors);
        }

    }

    private void loadData() {
        Disposable subscribe = Observable
                .create((ObservableOnSubscribe<List<HkChartData>>) emitter -> {
                    Thread.sleep(200);
                    Random random = new SecureRandom();
                   /* int r = random.nextInt(6);
                    if (r == 4) {
                        throw new Exception("接口发生异常");
                    }*/
                    List<HkChartData> list = new ArrayList<>();
                    List<String> keys=new ArrayList<>();
                    for (int j = 1; j <= mYNum; j++) {
                        keys.add( RandomUtils.randomChinese(random.nextInt(10) + 1) + j);
                    }
                    for (int i = 1; i <= mXNum; i++) {
                        HkChartData chartData = new HkChartData();
                        chartData.setName(i + "月");
                        for (int j = 1; j <= mYNum; j++) {
                            float f = random.nextInt(10000) / 10000f;
                            chartData.put(keys.get(j-1), i * 100 + j * 40 + f);
                        }
                        list.add(chartData);
                    }

                    emitter.onNext(list);
                    emitter.onComplete();

                })
                .compose(SchedulerUtils.apply())
                .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
                .subscribe(data -> {
                    //柱状图曲线图
                    List<MPCombinedKey> keys = new ArrayList<>();
                    String[] keystring = HkChartData.getKeys(data);
                    if (keystring.length > 1) {
                        String[] ks = new String[keystring.length - 1];
                        for (int i = 0; i < keystring.length - 1; i++) {
                            if (!mCombinedChart1.getStyleConfig().isStackBar()) {
                                keys.add(new MPCombinedKey(keystring[i], MPConstant.BAR_CHART, MPConstant.LEFT));
                            } else {
                                ks[i] = keystring[i];
                            }
                        }
                        if (mCombinedChart1.getStyleConfig().isStackBar()) {
                            keys.add(new MPCombinedKey(ks, MPConstant.BAR_CHART, MPConstant.LEFT));
                        }
                        keys.add(new MPCombinedKey(keystring[keystring.length - 1], MPConstant.LINE_CHART, MPConstant.RIGHT));
                        mCombinedChart1.getAxisRight().setEnabled(true);
                        mCombinedChart1.setKeys(keys);
                        SecureRandom secureRandom = new SecureRandom();
                        for (HkChartData item : data) {
                            item.put(keystring[keystring.length - 1], secureRandom.nextInt(100));
                        }


                    } else {
                        mCombinedChart1.setKeys(null);
                        mCombinedChart1.getAxisRight().setEnabled(false);
                    }
                    //并排堆叠
                    List<MPCombinedKey> keys2 = new ArrayList<>();
                    if (keystring.length >= 4) {
                        boolean line = keystring.length % 2 == 1;
                        for (int i = 0; i < keystring.length; i += 2) {
                            if (i + 1 < keystring.length) {
                                keys2.add(new MPCombinedKey(new String[]{keystring[i], keystring[i + 1]}, MPConstant.BAR_CHART, MPConstant.LEFT));
                            }
                        }
                        if (line) {
                            keys2.add(new MPCombinedKey(keystring[keystring.length - 1], MPConstant.LINE_CHART, MPConstant.RIGHT));
                            mCombinedChart11.getAxisRight().setEnabled(true);
                        }
                        mCombinedChart11.setKeys(keys2);
                    } else {
                        mCombinedChart11.setKeys(null);
                        mCombinedChart11.getAxisRight().setEnabled(false);
                    }

                    //并排堆叠 bar
                    List<MPBarKey> keys3 = new ArrayList<>();
                    if (keystring.length >= 4 && keystring.length % 2 == 0) {
                        for (int i = 0; i < keystring.length; i += 2) {
                            if (i + 1 < keystring.length) {
                                keys3.add(new MPBarKey(new String[]{keystring[i], keystring[i + 1]}));
                            }
                        }
                        mBarChart.setKeys(keys3);
                    } else {
                        mBarChart.setKeys(null);
                        mBarChart.getAxisRight().setEnabled(false);
                    }


                    mSwipeRefreshLayout.setRefreshing(false);
                    mBarChart.setHkChartData(data);
                    mLineChart.setHkChartData(data);
                    mCombinedChart1.setHkChartData(data);
                    SparseIntArray sparseIntArray=new SparseIntArray();
                    sparseIntArray.put(MPConstant.BAR_CHART, MPIconView.RECTANGLE_ARC);
                    sparseIntArray.put(MPConstant.LINE_CHART,MPIconView.LINE_CIRCLE);
                    mLegendViewGroup1.setData(MPChartUtils.computeLegend(mCombinedChart1.getData(), sparseIntArray), true);
                    mCombinedChart11.setHkChartData(data);
                    mCombinedChart2.setHkChartData(data);
                    mCombinedChart3.setHkChartData(data);


                    Random random = new SecureRandom();
                   /* int r = random.nextInt(6);
                    if (r == 4) {
                        throw new Exception("接口发生异常");
                    }*/
                    List<HkChartData> list = new ArrayList<>();
                    for (int i = 1; i <= mXNum; i++) {
                        HkChartData chartData = new HkChartData();
                        chartData.setName(i + "月");
                        for (int j = 1; j <= mYNum; j++) {
                            float f = random.nextInt(10000) / 100f;
                            chartData.put("占比" + j, f);
                        }
                        list.add(chartData);
                    }
                    mLineChartPercent.setHkChartData(list);
                }, throwable -> {
                    mSwipeRefreshLayout.setRefreshing(false);
                    throwable.printStackTrace();
                    mBarChart.error();
                    mLineChart.error();
                    mCombinedChart1.error();
                    mCombinedChart11.error();
                    mCombinedChart2.error();
                    mCombinedChart3.error();
                    mLineChartPercent.error();
                });


    }

}
